package javavis.jip2d.functions;

import java.util.ArrayList;

import javavis.base.ImageType;
import javavis.base.JIPException;
import javavis.jip2d.base.FunctionGroup;
import javavis.jip2d.base.JIPFunction;
import javavis.jip2d.base.JIPImage;
import javavis.jip2d.base.bitmaps.JIPImgBitmap;
import javavis.jip2d.base.geometrics.Edge;
import javavis.jip2d.base.geometrics.JIPImgGeometric;
import javavis.jip2d.base.geometrics.Junction;
import javavis.jip2d.base.geometrics.Point2D;
import javavis.jip2d.base.geometrics.Polygon2D;
import javavis.jip2d.base.geometrics.Segment;

/**
*Makes a reversal of image pixels and geometric data 
*from vertical axis.<BR>
*<ul><B>Input parameters:</B><BR>
*<li>img: Input image<BR><BR>
*</ul>
*<ul><B>Output parameters:</B><BR>
*<li>Image with the pixels reverses from vertical axis.<BR><BR>
*</ul>
*/
public class FMirror extends JIPFunction {
	private static final long serialVersionUID = 1393197595197881043L;

	public FMirror() {
		super();
		name = "FMirror";
		description = "Mirror an image";
		groupFunc = FunctionGroup.Manipulation;
	}

	public JIPImage processImg(JIPImage img) throws JIPException {
		int w = img.getWidth();
		int h = img.getHeight();
		ImageType t = img.getType();

		if (img instanceof JIPImgBitmap) {
			int b = ((JIPImgBitmap)img).getNumBands();
			JIPImgBitmap res = (JIPImgBitmap)JIPImage.newImage(b, w, h, t);
			for (int nb = 0; nb < b; nb++)
				for (int y = 0; y < h; y++)
					for (int x = 0; x < w; x++) {
						double ip = ((JIPImgBitmap)img).getPixel(nb, x, y);
						res.setPixel(nb, x, y, ((JIPImgBitmap)img).getPixel(nb, w - x - 1, y));
						res.setPixel(nb, w - x - 1, y, ip);
					}
			return res;
		} else {
			JIPImgGeometric res = (JIPImgGeometric)JIPImage.newImage(w, h, t);
			JIPImgGeometric imgGeom = (JIPImgGeometric)img;
			switch(imgGeom.getType()) {
				case POINT: ArrayList<Point2D> points = new ArrayList<Point2D>(imgGeom.getData());
							for (Point2D p : points) 
								p.setX(w - 1 - p.getX());
							res.setData(points);
							break;
				case SEGMENT: ArrayList<Segment> segments = new ArrayList<Segment>(imgGeom.getData());
							for (Segment s : segments) {
								s.getBegin().setX(w -1 - s.getBegin().getX());
								s.getEnd().setX(w -1 - s.getEnd().getX());
							}
							res.setData(segments);
							break;
				case EDGES: ArrayList<Edge> edges = new ArrayList<Edge>(imgGeom.getData());
							ArrayList<Point2D> pointAux;
							for (Edge e : edges) {
								pointAux = e.getData();
								for (Point2D p : pointAux) 
									p.setX(w - 1 - p.getX());
							}
							res.setData(edges);
							break;
				case POLY: ArrayList<Polygon2D> polys = new ArrayList<Polygon2D>(imgGeom.getData());
							ArrayList<Point2D> pointAux2;
							for (Polygon2D pol : polys) {
								pointAux2 = pol.getData();
								for (Point2D p : pointAux2) 
									p.setX(w - 1 - p.getX());
							}
							res.setData(polys);
							break;
				case JUNCTION: ArrayList<Junction> junctions = new ArrayList<Junction>(imgGeom.getData());
							for (Junction j : junctions) 
								j.setX(w - 1 - j.getX());
							res.setData(junctions);
							break;
			}
			return res;
		}
	}
}
